package com.example.listgame;

import androidx.appcompat.app.AppCompatActivity;

import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.SimpleAdapter;

import com.example.listgame.myfunctions.CustomDialog;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

public class LLKGameActivity extends AppCompatActivity {

    private int[] picture = new int[]{R.drawable.img1, R.drawable.img2,
            R.drawable.img3, R.drawable.img4, R.drawable.img5,
            R.drawable.img6, R.drawable.margin};
    private GridView mGridView;
    private DBOpenHelper dbOpenHelper;   //声明DBOpenHelper对象
    int temp = 0;
    int lastClicked;
    int numcolum;   //列数
    String username;   //传过来的昵称
    int score=0;    //记录分数
    ArrayList<HashMap<String, Integer>> listitem;   //创建ArrayList数列

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_l_l_k_game);
        mGridView = findViewById(R.id.gridview);
        dbOpenHelper = new DBOpenHelper(LLKGameActivity.this,"db_userinfo.db",null,1);   //实例化DBOpenHelper对象，用来创建数据库
        Bundle bundle = getIntent().getExtras();
        numcolum = bundle.getInt("number");    //获取上个Activity传过来的值
        username = bundle.getString("username");     //获取上个Activity传过来的昵称
        listitem = new ArrayList<HashMap<String, Integer>>();
        CreateStones();    //生成数据
        Collections.shuffle(listitem);     //随机打乱ArrayList的顺序
        DataBind();      //绑定数据
        /*建立点击事件*/
        mGridView.setNumColumns(numcolum); //设置列数
        mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                int temp1 = (int)(listitem.get(i).get("image"));
                /*第一个条件是判断点击的不是空的，第二个确认两次点击的不是同一个*/
                if (temp1 != R.drawable.margin && lastClicked != i){
                    if (temp == 0){
                        temp = temp1;
                    }else{
                        //判断点击的两个图标是否相同
                        if (temp1 == temp){
                            Point thispoint = argtopoint(i);  //将第二个点击的图标转换为点坐标
                            Point lastpoint = argtopoint(lastClicked);   //将第一个点击的图标转换为点坐标
                            /*用下面方法判断图标是否能被消掉*/
                            if (CheckIsItCanBeDestoryed(thispoint,lastpoint)){
                                 Clear(i);
                                 Clear(lastClicked);
                                 DataBind();
                                 score++;
                                 Finish(score);
                            }
                        }
                        temp = 0;
                    }
                    lastClicked = i;
                }
            }
        });
     }

    //生成数据，每次随机到的图标生成两次
    private void CreateStones() {
        for (int i = 0; i < (numcolum*numcolum/2); i++) {
            int num = (int) (Math.random() * 6);
            HashMap<String, Integer> map = new HashMap<String, Integer>();
            map.put("image", picture[num]);
            listitem.add(map);
            listitem.add(map);
        }
    }


    //绑定数据或者listitem改变后重新绑定
    private void DataBind(){
        SimpleAdapter simpleAdapter = new SimpleAdapter(LLKGameActivity.this,listitem,R.layout.layout_grid_view,new String[]{"image"},new int[]{R.id.image});
        mGridView.setAdapter(simpleAdapter);
    }


    //存储坐标点的方法
    class Point{
        int x;
        int y;
        Point(int x,int y){
            this.x = x;
            this.y = y;
        }
        Point(Point point){
            this.x = point.x;
            this.y = point.y;
        }
    }

    //把数字转换为坐标
    private Point argtopoint(int a){
        int x = a%numcolum;
        int y = a/numcolum;
        return new Point(x,y);
    }

    //把坐标转换为数字
    private int pointtoarg(Point point){
        return point.y*numcolum+point.x;
    }

    //判断这两个图标是否满足被消掉的条件
    private boolean CheckIsItCanBeDestoryed(Point point1,Point point2){
        /*四个边上相同的图标*/
        if (point1.x == 0 & point2.x == 0 & listitem.get(pointtoarg(point1)).get("image") != R.drawable.margin &
                listitem.get(pointtoarg(point2)).get("image") != R.drawable.margin){
            return true;
        }
        if (point1.y == 0 & point2.y == 0 & listitem.get(pointtoarg(point1)).get("image") != R.drawable.margin &
                listitem.get(pointtoarg(point2)).get("image") != R.drawable.margin){
            return true;
        }
        if (point1.x == numcolum-1 & point2.x == numcolum-1 & listitem.get(pointtoarg(point1)).get("image") != R.drawable.margin &
                listitem.get(pointtoarg(point2)).get("image") != R.drawable.margin){
            return true;
        }
        if (point1.y == numcolum-1 & point2.y == numcolum-1 & listitem.get(pointtoarg(point1)).get("image") != R.drawable.margin &
                listitem.get(pointtoarg(point2)).get("image") != R.drawable.margin){
            return true;
        }
        /*判断仅一条直线就可以连接的情况*/
        /*从竖直方向判断*/
        if (testVertical(new Point(point1),new Point(point2))){
            return true;
        }
        /*从水平方向判断*/
        if (testHorizontal(new Point(point1),new Point(point2))){
            return true;
        }
        /*判断有一个拐点并可以连接的情况*/
        /*拐点坐标的第一种情况*/
        Point newPoint1 = new Point(point1.x,point2.y);
        int newArg1 = pointtoarg(newPoint1);
        if (listitem.get(newArg1).get("image") == R.drawable.margin){
            if (testVertical(point1,new Point(newPoint1)) && testHorizontal(point2,new Point(newPoint1))){
                return true;
            }
        }
        /*拐点坐标的第二种情况*/
        Point newPoint2 = new Point(point2.x,point1.y);
        int newArg2 = pointtoarg(newPoint2);
        if (listitem.get(newArg2).get("image") == R.drawable.margin){
            if (testVertical(point2,new Point(newPoint2)) && testHorizontal(point1,new Point(newPoint2))){
                return true;
            }
        }

        /*判断有两个拐点并可以连接的情况*/
        Vector<Line> vector=new Vector<Line>();
        vector=Scan(new Point(point1), new Point(point2));
        if (!vector.isEmpty()) {
            for (int i = 0; i < vector.size(); i++) {
                Line line=vector.elementAt(i);
                //横线
                if (line.dirct==0) {
                    if (testVertical(new Point(point1), new Point(line.a)) && testVertical(new Point(point2), new Point(line.b))) {
                        return true;
                    }
                }else {
                    if (testHorizontal(new Point(point1), new Point(line.a)) && testHorizontal(new Point(point2), new Point(line.b))) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /*竖直方向连接的判断方法*/
    private boolean testVertical(Point point1,Point point2){
        /*定义一个boolean值，表示循环过程中是否碰到不为空的*/
        boolean a = true;
        if (point1.x == point2.x){
            /*distance值为1或-1*/
            int distance = (point1.y - point2.y)/Math.abs(point1.y - point2.y);
            while(point1.y != point2.y){
                point2.y += distance;
                int arg = pointtoarg(point2);
                /*如果对应坐标点不为空*/
                if(listitem.get(arg).get("image") != R.drawable.margin & point1.y != point2.y){
                    a = false;
                    break;
                }
            }
        }else {
            a = false;
        }
        return a;
    }

    /*水平方向连接的判断方法*/
    private boolean testHorizontal(Point point1,Point point2){
        /*定义一个boolean值，表示循环过程中是否碰到不为空的*/
        boolean b = true;
        if (point1.y == point2.y){
            /*distance值为1或-1*/
            int distance = (point1.x - point2.x)/Math.abs(point1.x - point2.x);
            while(point1.x != point2.x){
                point2.x += distance;
                int arg = pointtoarg(point2);
                /*如果对应坐标点不为空*/
                if(listitem.get(arg).get("image") != R.drawable.margin & point1.x != point2.x){
                    b = false;
                    break;
                }
            }
        }else {
            b = false;
        }
        return b;
    }


    private Vector<Line> Scan(Point p1, Point p2) {
        Vector<Line> v=new Vector<Line>();
        //查找A左边的线
        for (int y = p1.y; y >= 0; y--) {
            if (listitem.get(pointtoarg(new Point(p1.x, y))).get("image") == R.drawable.margin &&
                    listitem.get(pointtoarg(new Point(p2.x, y))).get("image") == R.drawable.margin &&
                    p1.x != p2.x &&
                    testHorizontal(new Point(p1.x,y), new Point(p2.x,y))) {
                v.add(new Line(0, new Point(p1.x,y), new Point(p2.x,y)));
            }
        }
        //查找A右边边的线
        for (int y = p1.y; y < (numcolum-1); y++) {
            if (listitem.get(pointtoarg(new Point(p1.x, y))).get("image") == R.drawable.margin &&
                    listitem.get(pointtoarg(new Point(p2.x, y))).get("image") == R.drawable.margin &&
                    p1.x != p2.x &&
                    testHorizontal(new Point(p1.x,y), new Point(p2.x,y))) {
                v.add(new Line(0, new Point(p1.x,y), new Point(p2.x,y)));
            }
        }
        //查找A上面的线
        for (int x = p1.x; x >= 0; x--) {
            if (listitem.get(pointtoarg(new Point(x,p1.y))).get("image") == R.drawable.margin &&
                    listitem.get(pointtoarg(new Point(x, p2.y))).get("image") == R.drawable.margin &&
                    p1.y != p2.y &&
                    testVertical(new Point(x,p1.y), new Point(x,p2.y))) {
                v.add(new Line(1, new Point(x,p1.y), new Point(x,p2.y)));
            }
        }
        //查找A下面的线
        for (int x = p1.x; x < (numcolum-1); x++) {
            if (listitem.get(pointtoarg(new Point(x,p1.y))).get("image") == R.drawable.margin &&
                    listitem.get(pointtoarg(new Point(x, p2.y))).get("image") == R.drawable.margin &&
                    p1.y != p2.y &&
                    testVertical(new Point(x,p1.y), new Point(x,p2.y))) {
                v.add(new Line(1, new Point(x,p1.y), new Point(x,p2.y)));
            }
        }
        return v;
    }

    /*将满足条件的图标消除*/
    private void Clear(int clear){
        HashMap<String,Integer> cHash = new HashMap<String,Integer>();
        cHash.put("image",R.drawable.margin);
        listitem.set(clear,cHash);
    }

    //Dialog结束提示框
    private void Dialog(){
        CustomDialog customDialog = new CustomDialog(LLKGameActivity.this);
        customDialog.setTitle("游戏结束").setMessage("得分为"+score).setAgain("再来一局", new CustomDialog.IOnAgainListener() {
            @Override
            public void onAgain(CustomDialog dialog) {
                Intent intent = new Intent(LLKGameActivity.this,CheckLevelActivity.class);
                startActivity(intent);
                LLKGameActivity.this.finish();
            }
        }).setBack("返回主菜单", new CustomDialog.IOnBackListener() {
            @Override
            public void onBack(CustomDialog dialog) {
                Intent intent = new Intent(LLKGameActivity.this,CheckLevelActivity.class);
                startActivity(intent);
                LLKGameActivity.this.finish();
            }
        }).show();

        /*更新数据库中的得分*/
        if (numcolum == 4) {
            Update("point");
        }else if (numcolum == 6){
            Update("mpoint");
        }else {
            Update("dpoint");
        }
    }

    /*更新数据库中得分的方法*/
    private void Update(String date){
        SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
        Cursor cursor = db.query("UserInfo", null, "username = ?", new String[]{username}, null, null, null);
        while (cursor.moveToNext()) {
            int point = cursor.getInt(cursor.getColumnIndex(date));
            if (score > point) {
                ContentValues values = new ContentValues();
                values.put(date, score);
                db.update("UserInfo", values, "username = ?", new String[]{username});
            }
        }
        cursor.close();
    }

    /*判断图标是否全部消除了*/
    private void Finish(int score){
        for (HashMap<String,Integer> fmap : listitem){
            if (fmap.get("image") != R.drawable.margin){
                return;
            }
        }
        Dialog();
    }

    /*这个用来判断两个拐点连接的时候用到*/
    class Line{
        Point a,b;
        int dirct;//1表示竖线，0表示横线
        public Line(int dirce, Point a, Point b) {
            this.a=a;
            this.b=b;
            this.dirct=dirce;
        }
    }

    protected void onDestroy() {
        super.onDestroy();
        if (dbOpenHelper!=null){
            dbOpenHelper.close();  //关闭数据库连接
        }
    }
}
